package cn.jn.lhm.netty.part08;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;

import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH;

/**
 * @author lhm 2753914576@qq.com
 * @time 2023/10/29 - 23:10
 **/
@Slf4j
public class TestHttp {
    public static void main(String[] args) {
        NioEventLoopGroup boss = new NioEventLoopGroup();
        NioEventLoopGroup worker = new NioEventLoopGroup(2);
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.channel(NioServerSocketChannel.class);
            serverBootstrap.group(boss, worker);
            serverBootstrap.childHandler(new ChannelInitializer<NioSocketChannel>() {
                @Override
                protected void initChannel(NioSocketChannel client) {
                    client.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG));
                    // 能同时处理服务端的编解码
                    // 会往下传递两个对象,一个是 HttpRequest(请求头) 一个是 HttpContent(请求体)
                    //client.pipeline().addLast(new HttpServerCodec());
                    client.pipeline().addLast(new HttpRequestDecoder());
                    client.pipeline().addLast(new HttpResponseEncoder());
                    // 专门处理 HttpContent 的入栈处理器
                    client.pipeline().addLast(new SimpleChannelInboundHandler<HttpContent>() {
                        @Override
                        protected void channelRead0(ChannelHandlerContext ctx, HttpContent msg) throws Exception {
                            log.info(msg.toString());
                            log.info(msg.content().toString(StandardCharsets.UTF_8));
                        }
                    });
                    // 专门处理 HttpRequest 的入栈处理器
                    client.pipeline().addLast(new SimpleChannelInboundHandler<HttpRequest>() {
                        @Override
                        protected void channelRead0(ChannelHandlerContext ctx, HttpRequest msg) throws Exception {
                            log.info("请求地址uri: {}", msg.uri());

                            // 构造响应
                            byte[] bytes = "<h1>welcome Client</h1>".getBytes(StandardCharsets.UTF_8);
                            DefaultFullHttpResponse response = new DefaultFullHttpResponse(msg.protocolVersion(), HttpResponseStatus.OK);
                            response.headers().set(CONTENT_LENGTH, bytes.length);
                            response.content().writeBytes(bytes);

                            client.writeAndFlush(response);
                        }
                    });
                }
            });
            ChannelFuture future = serverBootstrap.bind(8080).sync();
            future.channel().closeFuture().sync();
        } catch (Exception e) {
            log.error("server error...", e);
        } finally {
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }
    }
}
